package com.eiisan.core.util.api;

import lombok.ToString;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.util.Collection;
import java.util.Optional;

/**
 * @Description: 通用返回参数
 * @Author gragonfly
 * @Date 2019/6/22
 **/
@ToString
public class Result<T> implements Serializable {
    /**
     * 状态码
     */
    private int code;

    public int getCode() {
        return code;
    }

    /**
     * 提示信息
     */
    String message;

    public String getMessage() {
        return message;
    }

    /**
     * 数据
     */
    private T data;

    public T getData() {
        return data;
    }

    public Result() {
    }

    private Result(IResultCode resultCode) {
        this.code = resultCode.getCode();
        this.message = resultCode.getDesc();
    }

    private Result(String message, IResultCode resultCode) {
        this.code = resultCode.getCode();
        this.message = message;
    }

    private Result(IResultCode resultCode, T data) {
        this.code = resultCode.getCode();
        this.message = resultCode.getDesc();
        this.data = data;
    }

    /**
     * 判断返回是否为成功
     */
    public static boolean isSuccess(@Nullable Result<?> result) {
        return Optional.ofNullable(result)
                .map(r -> ResultCode.SUCCESS.code == r.code)
                .orElse(Boolean.FALSE);
    }

    /**
     * 判断返回是否失败
     */
    public static boolean isNotSuccess(@Nullable Result<?> result) {
        return !Result.isSuccess(result);
    }

    /**
     * 返回成功结果
     */
    public static <T> Result<T> success() {
        return new Result<>(ResultCode.SUCCESS);
    }

    /**
     * 返回成功结果
     */
    public static <T> Result<T> success(T data) {
        Assert.notNull(data, "data must not be null");
        return new Result<>(ResultCode.SUCCESS, data);
    }


    /**
     * 返回失败结果(无信息)
     */
    public static <T> Result<T> fail() {
        return new Result<>(ResultCode.FAILURE);
    }

    /**
     * 返回失败结果(有信息)
     */
    public static <T> Result<T> fail(String message) {
        Assert.notNull(message, "message must not be null");
        return new Result<>(message, ResultCode.FAILURE);
    }

    /**
     * 返回请求参数错误(无信息)
     */
    public static <T> Result<T> errorRequest() {
        return new Result<>(ResultCode.ERROR_PARAMETER);
    }

    /**
     * 返回请求参数错误(有信息)
     */
    public static <T> Result<T> errorRequest(String message) {
        Assert.notNull(message, "message must not be null");
        return new Result<>(message, ResultCode.ERROR_PARAMETER);
    }

    /**
     * 返回服务器错误结果(无信息)
     */
    public static <T> Result<T> errorServe() {
        return new Result<>(ResultCode.ERROR_SERVER);
    }

    /**
     * 返回服务器错误结果(有信息)
     */
    public static <T> Result<T> errorServe(String message) {
        return new Result<>(message, ResultCode.ERROR_SERVER);
    }

    /**
     * 返回服务器错误结果(有信息)
     */
    public static <T> Result<T> errorServe(Throwable message) {
        Assert.notNull(message, "message must not be null");
        return new Result<>(message.getMessage(), ResultCode.ERROR_SERVER);
    }

    /**
     * 返回没找到请求结果 404
     */
    public static <T> Result<T> notFound() {
        return new Result<>(ResultCode.NOT_FOUND);
    }

    /**
     * 返回未登录结果
     */
    public static <T> Result<T> notLogin() {
        return new Result<>(ResultCode.NOT_LOGIN);
    }

    /**
     * 返回已过期结果
     */
    public static <T> Result<T> expired() {
        return new Result<>(ResultCode.EXPIRED);
    }

    /**
     * 返回未通过验证结果
     */
    public static <T> Result<T> noAuth() {
        return new Result<>(ResultCode.NO_AUTH);
    }

    /**
     * 返回缺少操作权限结果
     */
    public static <T> Result<T> noAccess() {
        return new Result<>(ResultCode.NO_ACCESS);
    }

    /**
     * 返回重复请求结果
     */
    public static <T> Result<T> repeatRequest() {
        return new Result<>(ResultCode.REPEAT_REQUEST);
    }

    /**
     * 返回服务器繁忙结果
     */
    public static <T> Result<T> busyServe() {
        return new Result<>(ResultCode.BUSY_SERVER);
    }


    /**
     * 返回分页查询类型结果(仅在成功时使用)<br>
     * vo.data的类型为com.eiisan.beans.response.PageData
     *
     * @see PageData
     */
    public static <T> Result page(int pageNum, int pageSize, long total, Collection<T> data) {
        Assert.notNull(data, "data must not be null");
        return new Result<>(ResultCode.SUCCESS, new PageData<>(pageNum, pageSize, total, data));
    }

    /**
     * 返回分页查询类型结果(仅在成功时使用)<br>
     * vo.data的类型为com.eiisan.beans.response.PageData
     *
     * @see PageData
     */
    public static <T> Result page(PageData<T> pageData) {
        Assert.notNull(pageData, "page must not be null");
        Assert.notNull(pageData.getPageNum(), "page.getPageNum() must not be null");
        Assert.notNull(pageData.getPageSize(), "page.getPageSize() must not be null");
        Assert.notNull(pageData.getTotal(), "page.getTotal() must not be null");
        Assert.notNull(pageData.getPage(), "page.getPage() must not be null");
        return new Result<>(ResultCode.SUCCESS, pageData);
    }
}
